Repository navigation
feat(api): MCP OAuth discovery on /mcp (RFC-0044 phase 1) - #152
Merged
Merged
Conversation
With `McpMountOptions.oauth` (issuer, resource) the 401 of /mcp carries a WWW-Authenticate challenge naming the RFC 9728 protected resource metadata and the scopes to request, the metadata is served at both well-known forms, and a token principal (`Principal.grantId`, phase 2) calling a tool without a scope its member's role holds gets a 403 insufficient_scope step-up challenge before the handler runs. The /mcp route moves to mcp-mount.ts; createApi shrinks and the size baseline is tightened. Shared suite on better-sqlite3 and Miniflare D1; ADR-0004 addendum points at RFC-0044. Refs #144 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Madraka <8898640+Madraka@users.noreply.github.com>
The docs site publishes only pages on the branch; the RFC file lands with #146. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Madraka <8898640+Madraka@users.noreply.github.com>
RFC-0044 decision 10: the playground stays out of OAuth, so the two discovery routes are on the deny list (block "mcp"). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Madraka <8898640+Madraka@users.noreply.github.com>
The RFC file is on main since #146. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Signed-off-by: Madraka <8898640+Madraka@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Phase 1 of RFC-0044 (#144, accepted 2026-11-08): OAuth discovery for remote MCP clients, behind a new
McpMountOptions.oauthoption (issuer,resource, optionalscopesSupported,resourceName,documentation)./mcp401 answersWWW-Authenticate: Bearer resource_metadata="…/.well-known/oauth-protected-resource/mcp", scope="…"(RFC 9728 §5.1, RFC 6750), witherror="invalid_token"when a bearer was presented. The JSON body is unchanged.scopes_supportedisscopesForMode("edits"), the minimal set, as the RFC decides.Principal.grantId, set by phase 2) calling a tool whose scopes the token lacks but the member's role holds gets403 insufficient_scopewith every missing scope in one challenge, decided from the static tool policy table before the JSON-RPC handler runs. Keys are never challenged (they cannot re-authorize), nor is a scope the role lacks (the client would loop)./mcproute moved fromcreateApitopackages/api/src/mcp-mount.ts;createApishrank from 217 to 188 lines and the size baseline is tightened.src/testing-mcp-oauth.tson better-sqlite3 and Miniflare D1 (test/mcp-oauth.test.ts): challenge,invalid_token, both documents, bare 401 without the option, step-up for a grant principal, no challenge for a Contributor's grant or for an agent key.route-scopes.test.tsdeclares the two well-known routes.@cloudhal/apiand@cloudhal/agent-runtime.Not wired into the admin Worker or
cloudhal studioyet: a deployment that sets the option would advertise an issuer whose metadata does not exist until phase 2 (the Better Auth authorization server). Phase 2 also needscloudhal studio --base-url(#143).Checklist
pnpm checkandcargo test --workspacepass locally — ranpnpm lint(Biome 2.6.2, error level),tsc --noEmitfor@cloudhal/apiand@cloudhal/agent-runtime,node scripts/size-check.ts, andvitest run test/mcp-oauth.test.ts test/route-scopes.test.ts test/agent-key-auth.test.ts(24 tests, both backends). The full suites were not run on the owner's machine by request; CI runs them.pnpm genwas run and generated files are committed (docs/adr/0001) — n/apnpm changesetaddedgit commit -s, DCO)🤖 Generated with Claude Code